using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

namespace GameSystems
{
    /// <summary>
    /// 游戏登录系统 - 处理用户认证、登录状态管理和相关UI交互
    /// </summary>
    public class GameLoginSystem : MonoBehaviour
    {
        #region Events

        /// <summary>
        /// 登录成功事件
        /// </summary>
        [Serializable] public class LoginSuccessEvent : UnityEvent<string> { }

        /// <summary>
        /// 登录失败事件
        /// </summary>
        [Serializable] public class LoginFailedEvent : UnityEvent<string> { }

        /// <summary>
        /// 登录状态改变事件
        /// </summary>
        [Serializable] public class LoginStateChangedEvent : UnityEvent<bool> { }

        #endregion

        #region Serialized Fields

        [Header("登录配置")]
        [Tooltip("是否启用自动登录")]
        [SerializeField] private bool enableAutoLogin = false;

        [Tooltip("最大登录尝试次数")]
        [SerializeField] private int maxLoginAttempts = 3;

        [Tooltip("登录超时时间（秒）")]
        [SerializeField] private float loginTimeout = 30f;

        [Tooltip("是否记住用户名")]
        [SerializeField] private bool rememberUsername = true;

        [Header("UI组件引用")]
        [Tooltip("用户名输入框")]
        [SerializeField] private InputField usernameInputField;

        [Tooltip("密码输入框")]
        [SerializeField] private InputField passwordInputField;

        [Tooltip("登录按钮")]
        [SerializeField] private Button loginButton;

        [Tooltip("注册按钮")]
        [SerializeField] private Button registerButton;

        [Tooltip("忘记密码按钮")]
        [SerializeField] private Button forgotPasswordButton;

        [Tooltip("加载指示器")]
        [SerializeField] private GameObject loadingIndicator;

        [Tooltip("错误信息文本")]
        [SerializeField] private Text errorMessageText;

        [Header("调试选项")]
        [Tooltip("是否启用调试日志")]
        [SerializeField] private bool enableDebugLogs = true;

        [Tooltip("测试用户名")]
        [SerializeField] private string testUsername = "testuser";

        [Tooltip("测试密码")]
        [SerializeField] private string testPassword = "testpass";

        #endregion

        #region Events

        [Header("事件回调")]
        [Tooltip("登录成功时触发")]
        public LoginSuccessEvent OnLoginSuccess;

        [Tooltip("登录失败时触发")]
        public LoginFailedEvent OnLoginFailed;

        [Tooltip("登录状态改变时触发")]
        public LoginStateChangedEvent OnLoginStateChanged;

        #endregion

        #region Private Fields

        private bool isLoggedIn = false;
        private int currentLoginAttempts = 0;
        private Coroutine loginTimeoutCoroutine;
        private bool isComponentValidated = false;

        // 缓存的组件引用
        private CanvasGroup canvasGroup;

        #endregion

        #region Unity Lifecycle

        /// <summary>
        /// 初始化组件
        /// </summary>
        private void Awake()
        {
            ValidateComponents();
            CacheComponents();
            InitializeUI();
        }

        /// <summary>
        /// 启动时的初始化
        /// </summary>
        private void Start()
        {
            LoadSavedCredentials();

            if (enableAutoLogin)
            {
                TryAutoLogin();
            }

            LogDebug("GameLoginSystem 初始化完成");
        }

        /// <summary>
        /// 清理资源
        /// </summary>
        private void OnDestroy()
        {
            CleanupEvents();

            if (loginTimeoutCoroutine != null)
            {
                StopCoroutine(loginTimeoutCoroutine);
            }
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// 执行登录
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        public void Login(string username, string password)
        {
            if (isLoggedIn)
            {
                LogWarning("用户已经登录");
                return;
            }

            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                ShowError("用户名和密码不能为空");
                OnLoginFailed?.Invoke("用户名和密码不能为空");
                return;
            }

            if (currentLoginAttempts >= maxLoginAttempts)
            {
                ShowError($"登录尝试次数过多，请稍后再试");
                OnLoginFailed?.Invoke("登录尝试次数过多");
                return;
            }

            StartLoginProcess(username, password);
        }

        /// <summary>
        /// 注销当前用户
        /// </summary>
        public void Logout()
        {
            if (!isLoggedIn)
            {
                LogWarning("用户未登录");
                return;
            }

            isLoggedIn = false;
            currentLoginAttempts = 0;

            OnLoginStateChanged?.Invoke(false);

            if (rememberUsername && usernameInputField != null)
            {
                SaveUsername(usernameInputField.text);
            }

            LogDebug("用户已注销");
        }

        /// <summary>
        /// 检查是否已登录
        /// </summary>
        /// <returns>登录状态</returns>
        public bool IsLoggedIn()
        {
            return isLoggedIn;
        }

        /// <summary>
        /// 使用测试账号登录
        /// </summary>
        [ContextMenu("使用测试账号登录")]
        public void LoginWithTestAccount()
        {
            Login(testUsername, testPassword);
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// 验证必要的组件
        /// </summary>
        private void ValidateComponents()
        {
            if (usernameInputField == null)
            {
                LogError("用户名输入框未设置");
                return;
            }

            if (passwordInputField == null)
            {
                LogError("密码输入框未设置");
                return;
            }

            if (loginButton == null)
            {
                LogError("登录按钮未设置");
                return;
            }

            isComponentValidated = true;
        }

        /// <summary>
        /// 缓存组件引用
        /// </summary>
        private void CacheComponents()
        {
            canvasGroup = GetComponent<CanvasGroup>();
        }

        /// <summary>
        /// 初始化UI
        /// </summary>
        private void InitializeUI()
        {
            if (!isComponentValidated) return;

            // 设置按钮事件
            loginButton.onClick.AddListener(OnLoginButtonClicked);

            if (registerButton != null)
            {
                registerButton.onClick.AddListener(OnRegisterButtonClicked);
            }

            if (forgotPasswordButton != null)
            {
                forgotPasswordButton.onClick.AddListener(OnForgotPasswordButtonClicked);
            }

            // 设置输入框事件
            usernameInputField.onValueChanged.AddListener(OnInputFieldChanged);
            passwordInputField.onValueChanged.AddListener(OnInputFieldChanged);
            passwordInputField.onEndEdit.AddListener(OnPasswordFieldEndEdit);

            // 初始状态
            UpdateLoginButtonState();
            HideError();
            SetLoadingState(false);
        }

        /// <summary>
        /// 开始登录流程
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        private void StartLoginProcess(string username, string password)
        {
            SetLoadingState(true);
            HideError();

            // 启动超时检查
            loginTimeoutCoroutine = StartCoroutine(LoginTimeoutCoroutine());

            // 模拟登录验证（在实际项目中，这里应该是网络请求）
            StartCoroutine(SimulateLoginValidation(username, password));
        }

        /// <summary>
        /// 模拟登录验证协程
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns></returns>
        private IEnumerator SimulateLoginValidation(string username, string password)
        {
            // 模拟网络延迟
            yield return new WaitForSeconds(2f);

            // 停止超时检查
            if (loginTimeoutCoroutine != null)
            {
                StopCoroutine(loginTimeoutCoroutine);
                loginTimeoutCoroutine = null;
            }

            // 简单的验证逻辑（实际项目中应该是服务器验证）
            bool isValid = ValidateCredentials(username, password);

            SetLoadingState(false);

            if (isValid)
            {
                OnLoginSuccessInternal(username);
            }
            else
            {
                OnLoginFailedInternal("用户名或密码错误");
            }
        }

        /// <summary>
        /// 验证用户凭据
        /// </summary>
        /// <param name="username">用户名</param>
        /// <param name="password">密码</param>
        /// <returns>验证结果</returns>
        private bool ValidateCredentials(string username, string password)
        {
            // 这里是简单的测试验证
            // 实际项目中应该连接到认证服务器
            return username == testUsername && password == testPassword;
        }

        /// <summary>
        /// 登录成功处理
        /// </summary>
        /// <param name="username">用户名</param>
        private void OnLoginSuccessInternal(string username)
        {
            isLoggedIn = true;
            currentLoginAttempts = 0;

            if (rememberUsername)
            {
                SaveUsername(username);
            }

            OnLoginSuccess?.Invoke(username);
            OnLoginStateChanged?.Invoke(true);

            LogDebug($"用户 {username} 登录成功");
        }

        /// <summary>
        /// 登录失败处理
        /// </summary>
        /// <param name="errorMessage">错误信息</param>
        private void OnLoginFailedInternal(string errorMessage)
        {
            currentLoginAttempts++;
            ShowError(errorMessage);
            OnLoginFailed?.Invoke(errorMessage);

            LogWarning($"登录失败: {errorMessage} (尝试次数: {currentLoginAttempts}/{maxLoginAttempts})");
        }

        /// <summary>
        /// 登录超时协程
        /// </summary>
        /// <returns></returns>
        private IEnumerator LoginTimeoutCoroutine()
        {
            yield return new WaitForSeconds(loginTimeout);

            if (!isLoggedIn)
            {
                SetLoadingState(false);
                OnLoginFailedInternal("登录超时，请检查网络连接");
            }
        }

        /// <summary>
        /// 尝试自动登录
        /// </summary>
        private void TryAutoLogin()
        {
            string savedUsername = LoadSavedUsername();

            if (!string.IsNullOrEmpty(savedUsername))
            {
                usernameInputField.text = savedUsername;
                // 在实际项目中，自动登录可能需要保存的token或会话
                // 这里只是示例，实际应该更安全
                LogDebug("尝试自动登录");
            }
        }

        /// <summary>
        /// 保存用户名
        /// </summary>
        /// <param name="username">用户名</param>
        private void SaveUsername(string username)
        {
            PlayerPrefs.SetString("LastUsername", username);
            PlayerPrefs.Save();
        }

        /// <summary>
        /// 加载保存的用户名
        /// </summary>
        /// <returns>保存的用户名</returns>
        private string LoadSavedUsername()
        {
            return PlayerPrefs.GetString("LastUsername", "");
        }

        /// <summary>
        /// 加载保存的凭据
        /// </summary>
        private void LoadSavedCredentials()
        {
            if (rememberUsername)
            {
                string savedUsername = LoadSavedUsername();
                if (!string.IsNullOrEmpty(savedUsername))
                {
                    usernameInputField.text = savedUsername;
                }
            }
        }

        /// <summary>
        /// 设置加载状态
        /// </summary>
        /// <param name="isLoading">是否正在加载</param>
        private void SetLoadingState(bool isLoading)
        {
            if (loadingIndicator != null)
            {
                loadingIndicator.SetActive(isLoading);
            }

            if (canvasGroup != null)
            {
                canvasGroup.interactable = !isLoading;
            }

            if (loginButton != null)
            {
                loginButton.interactable = !isLoading;
            }
        }

        /// <summary>
        /// 显示错误信息
        /// </summary>
        /// <param name="message">错误信息</param>
        private void ShowError(string message)
        {
            if (errorMessageText != null)
            {
                errorMessageText.text = message;
                errorMessageText.gameObject.SetActive(true);
            }
        }

        /// <summary>
        /// 隐藏错误信息
        /// </summary>
        private void HideError()
        {
            if (errorMessageText != null)
            {
                errorMessageText.gameObject.SetActive(false);
            }
        }

        /// <summary>
        /// 更新登录按钮状态
        /// </summary>
        private void UpdateLoginButtonState()
        {
            if (loginButton != null && usernameInputField != null && passwordInputField != null)
            {
                bool hasInput = !string.IsNullOrEmpty(usernameInputField.text) &&
                               !string.IsNullOrEmpty(passwordInputField.text);
                loginButton.interactable = hasInput && !isLoggedIn;
            }
        }

        /// <summary>
        /// 清理事件
        /// </summary>
        private void CleanupEvents()
        {
            if (loginButton != null)
            {
                loginButton.onClick.RemoveAllListeners();
            }

            if (registerButton != null)
            {
                registerButton.onClick.RemoveAllListeners();
            }

            if (forgotPasswordButton != null)
            {
                forgotPasswordButton.onClick.RemoveAllListeners();
            }

            if (usernameInputField != null)
            {
                usernameInputField.onValueChanged.RemoveAllListeners();
            }

            if (passwordInputField != null)
            {
                passwordInputField.onValueChanged.RemoveAllListeners();
                passwordInputField.onEndEdit.RemoveAllListeners();
            }
        }

        #endregion

        #region UI Event Handlers

        /// <summary>
        /// 登录按钮点击事件
        /// </summary>
        private void OnLoginButtonClicked()
        {
            if (usernameInputField != null && passwordInputField != null)
            {
                Login(usernameInputField.text, passwordInputField.text);
            }
        }

        /// <summary>
        /// 注册按钮点击事件
        /// </summary>
        private void OnRegisterButtonClicked()
        {
            LogDebug("注册按钮被点击");
            // 这里可以打开注册界面
        }

        /// <summary>
        /// 忘记密码按钮点击事件
        /// </summary>
        private void OnForgotPasswordButtonClicked()
        {
            LogDebug("忘记密码按钮被点击");
            // 这里可以打开密码重置界面
        }

        /// <summary>
        /// 输入框内容改变事件
        /// </summary>
        /// <param name="value">输入内容</param>
        private void OnInputFieldChanged(string value)
        {
            UpdateLoginButtonState();
            HideError();
        }

        /// <summary>
        /// 密码输入框结束编辑事件
        /// </summary>
        /// <param name="value">密码内容</param>
        private void OnPasswordFieldEndEdit(string value)
        {
            // 按回车键提交登录
            if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
            {
                OnLoginButtonClicked();
            }
        }

        #endregion

        #region Debug Methods

        /// <summary>
        /// 输出调试日志
        /// </summary>
        /// <param name="message">日志信息</param>
        private void LogDebug(string message)
        {
            if (enableDebugLogs)
            {
                Debug.Log($"[GameLoginSystem] {message}");
            }
        }

        /// <summary>
        /// 输出警告日志
        /// </summary>
        /// <param name="message">警告信息</param>
        private void LogWarning(string message)
        {
            if (enableDebugLogs)
            {
                Debug.LogWarning($"[GameLoginSystem] {message}");
            }
        }

        /// <summary>
        /// 输出错误日志
        /// </summary>
        /// <param name="message">错误信息</param>
        private void LogError(string message)
        {
            Debug.LogError($"[GameLoginSystem] {message}");
        }

        #endregion
    }
}
